package com.aimusic.Handler;

import com.aimusic.domain.dto.WebSocketMessage;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
@Slf4j
public class ChatWebSocketHandler extends TextWebSocketHandler {

    // 存储用户会话，key为userId
    private static final Map<String, WebSocketSession> userSessions = new ConcurrentHashMap<>();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 从会话属性中获取用户ID（拦截器设置）
        String userId = (String) session.getAttributes().get("userId");
        if (userId != null) {
            userSessions.put(userId, session);
            System.out.println("用户[" + userId + "]建立WebSocket连接，当前在线人数：" + userSessions.size());
        } else {
            // 无userId时关闭连接
            session.close(CloseStatus.POLICY_VIOLATION.withReason("缺少用户ID"));
        }
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        System.out.println("收到消息：" + payload);

        // 1. 解析消息
        WebSocketMessage webSocketMessage = parseMessage(payload);
        if (webSocketMessage == null) {
            // 解析失败处理...
            return;
        }

        // 2. 优先处理心跳包（提前判断，跳过后续校验）
        if ("ping".equals(webSocketMessage.getType())) {
            session.sendMessage(new TextMessage("{\"type\":\"pong\"}"));
            return; // 直接返回，不执行后续的接收者ID校验
        }

        // 3. 再校验接收者ID（此时只剩业务消息，必须校验）
        String receiverId = webSocketMessage.getReceiverId();
        if (receiverId == null || receiverId.trim().isEmpty()) {
            // 缺少接收者ID处理...
            return;
        }

        // 4. 转发业务消息（如聊天消息）
        boolean sendSuccess = sendMessageToUser(receiverId, webSocketMessage);
        log.info("发送消息：", sendSuccess);
        // ...后续处理
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        String userId = (String) session.getAttributes().get("userId");
        if (userId != null) {
            userSessions.remove(userId);
            System.out.println("用户[" + userId + "]断开WebSocket连接，当前在线人数：" + userSessions.size());
        }
    }

    // 向指定用户发送消息
    private boolean sendMessageToUser(String userId, WebSocketMessage message) {
        // 校验userId非空
        if (userId == null || userId.trim().isEmpty()) {
            System.err.println("发送失败：用户ID为空");
            return false;
        }

        WebSocketSession session = userSessions.get(userId);
        if (session != null && session.isOpen()) {
            try {
                // 序列化为JSON字符串发送
                String msgJson = JSONObject.toJSONString(message);
                session.sendMessage(new TextMessage(msgJson));
                return true;
            } catch (Exception e) {
                System.err.println("向用户[" + userId + "]发送消息失败：" + e.getMessage());
            }
        } else {
            System.out.println("用户[" + userId + "]不在线或会话已关闭");
        }
        return false;
    }

    // 解析消息（反序列化时匹配构造器）
    private WebSocketMessage parseMessage(String payload) {
        try {
            // FastJSON会自动根据类的字段匹配反序列化，无需手动调用构造器
            return JSONObject.parseObject(payload, WebSocketMessage.class);
        } catch (Exception e) {
            System.err.println("解析消息失败：" + e.getMessage() + "，消息内容：" + payload);
            return null;
        }
    }
}